home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 / Ham Radio 2000.iso / ham2000 / vhf / locator / loceng.c < prev    next >
C/C++ Source or Header  |  1992-10-17  |  3KB  |  111 lines

  1. //   ------------------------------------------------------------------------------------------------------------
  2. //                Distance and direction computation subprograms
  3. //                     Code written 1984 - my second C program!
  4. //                     only few modifications (new locs_to_bearing)
  5. //                     made after that year
  6. //   ------------------------------------------------------------------------------------------------------------
  7.  
  8. #include "locowl.h"
  9. #include <ctype.h>
  10. #include <math.h>
  11.  
  12. #define PI 3.141592653589
  13.  
  14. struct location {
  15.     double longit;
  16.     double latit;
  17. };
  18.  
  19. struct polar {
  20.     double distance;
  21.     double direction;
  22. };
  23.  
  24. int locs_to_bearing (char far *from, char far *to,
  25.                     double *distance, double *direction)
  26. {
  27.     struct location from_spheric, to_spheric;
  28.     struct polar bearing;
  29.     int from_status, to_status;
  30.     int convert (char far *, struct location *);
  31.     int transform (struct location *, struct location *, struct polar *);
  32.  
  33.     from_status = convert (from, &from_spheric);
  34.     to_status = convert (to, &to_spheric);
  35.  
  36.     if (from_status+to_status)
  37.         return (from_status + 2 * to_status);
  38.  
  39.     transform (&from_spheric, &to_spheric, &bearing);
  40.  
  41.     *distance = bearing.distance;
  42.     *direction = 180.0 / PI * bearing.direction;
  43.  
  44.     return 0;
  45. }
  46.  
  47. static int convert(loc,place)
  48. char far *loc;
  49. struct location *place;
  50. {
  51.         char mark;
  52.         int i;
  53.         int c;
  54.         char locator[6];
  55.  
  56.         for ( i=0; i<=5; i++ ) {
  57.           locator[i] = tolower(loc[i]);
  58.         }
  59.  
  60.         for ( i=0; i<=1; i++ ) {
  61.           if ((locator[i]<'a')||(locator[i]>'r')) return 1;
  62.         }
  63.  
  64.         for ( i=2; i<=3; i++ ) {
  65.           if ( (locator[i]<'0')||(locator[i]>'9') ) return 1;
  66.         }
  67.  
  68.         for ( i=4; i<=5; i++ ) {
  69.           if ( (locator[i]<'a')||(locator[i]>'x') ) return 1;
  70.         }
  71.  
  72.         (place->latit) = 10*(locator[1] - 'a') - 90;
  73.         (place->latit) += locator[3] - '0';
  74.         (place->latit) += (locator[5] - 'a')/24.0 + 1/48.0;
  75.         (place->latit) *= PI/180.0;
  76.  
  77.         (place->longit) = 20*(locator[0] - 'a') - 180;
  78.         (place->longit) += 2*(locator[2] - '0');
  79.         (place->longit) += (locator[4] - 'a')/12.0 + 1/24.0;
  80.         (place->longit) *= PI/180.0;
  81.  
  82.         return 0;
  83.  
  84. }
  85.  
  86. static int transform(from,to,dd)
  87. struct location *from, *to;
  88. struct polar *dd;
  89. {
  90.  
  91.     double temp,nominator,radius;
  92.  
  93.     radius = 180.0 /PI * (111.1451 + 0.56 * sin (to->latit + from->latit - PI/2.0));
  94.  
  95.     (dd->distance) = radius * acos( temp = ( sin(to->latit) * sin(from->latit)
  96.          + cos(to->latit) * cos(from->latit) * cos(to->longit - from->longit)) );
  97.  
  98.         if (dd->distance < 0.1) {
  99.            dd->direction = 0;
  100.         }
  101.         else {
  102.            (dd->direction) = atan(( cos(from->latit)
  103.                                      * sin(to->longit - from->longit)
  104.                                      * cos(to->latit) )
  105.              / ( nominator = ( sin(to->latit) - temp * sin(from->latit) ) ) );
  106.            if (nominator<0) dd->direction -= PI;
  107.            if (dd->direction<0) dd->direction += 2*PI;
  108.         }
  109.     return 0;
  110. }
  111.